import { _decorator, Animation, animation, color, Component, EditBox, instantiate, Node, Prefab, resources, Sprite, Tween, tween, UIOpacity, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

const colorRandom = ["#1D44E2", "#F10B5E", "#F1D50B", "#20201D", "#6D6D52"]
const row = 10;
const col = 10;
const targetRwo = 6  //m
const targetCol = 5  //n

@ccclass('main')
export class main extends Component {
    @property({ type: Node })
    matrix: Node = null;

    @property({ type: Node })
    matrixList: Node = null;

    @property({ type: Node })
    matrixItem: Node = null;

    @property({ type: Node })
    editBoxX: Node = null;

    @property({ type: Node })
    editBoxY: Node = null;

    @property({ type: Node })
    startBtn: Node = null;

    private probabilityArr: number[] = []
    private addX: number = 0;
    private addY: number = 0;

    start() {
        this.matrixItem.active = false
        this.startBtn.setScale(0, 0, 0)

        this.btnStarAni()
        this.startBtn.on(Node.EventType.TOUCH_START, this.touchStartHandelr)
        this.startBtn.on(Node.EventType.TOUCH_CANCEL, this.touchCancelHandler)
        this.startBtn.on(Node.EventType.TOUCH_END, this.touchEndHandler)
    }

    btnStarAni() {
        tween(this.startBtn).to(0.5, { scale: new Vec3(1, 1, 1) }).call(() => {
            this.btnReplaceAni(1)
        }).tag(100).start()
    }

    btnReplaceAni(scaleNum: number) {
        tween(this.startBtn).repeatForever(
            tween().to(0.2, { scale: new Vec3(scaleNum + 0.1, scaleNum + 0.1, scaleNum + 0.1) })
                .to(0.2, { scale: new Vec3(scaleNum, scaleNum, scaleNum) })
        ).start()
    }

    touchStartHandelr = () => {
        this.startBtn.setScale(0.9, 0.9, 0.9)
        let _starDOwm = this.startBtn.getChildByName("down");
        _starDOwm.active = true
        this.btnReplaceAni(0.9)
    }

    resetBtn() {

        this.startBtn.setScale(1, 1, 1)
        let _starDOwm = this.startBtn.getChildByName("down");
        _starDOwm.active = false
        this.btnReplaceAni(1)

    }

    touchCancelHandler = () => {
        this.resetBtn()
    }

    touchEndHandler = () => {
        this.resetBtn()
        let addNumX = this.editBoxX.getComponent(EditBox).string || 0
        this.addX = Number(addNumX) / 100
        let addNumY = this.editBoxY.getComponent(EditBox).string || 0
        this.addY = Number(addNumY) / 100
        this.showRandomMatrix()
        this.starColorAni()
    }

    showRandomMatrix() {
        this.probabilityArr = []
        let initalProab = 1 / colorRandom.length
        for (let initalIndex = 0; initalIndex < colorRandom.length; initalIndex++) {
            this.probabilityArr.push(initalProab)
        }
        for (let index = 0; index < col * row; index++) {
            let _item = this.matrixList.getChildByName(`item${index + 1}`)
            if (!_item) {
                _item = instantiate(this.matrixItem);
                _item.active = true
                _item.setParent(this.matrixList)
                _item.name = `item${index + 1}`
            }
            //每个点可选 5 种颜⾊中的 1 种
            let colorIndex = this.getRandomInt(0, colorRandom.length - 1)
            _item["data"] = colorIndex
            //点(1, 1)随机在 5 个颜⾊中选取
            if (index == 0 && colorRandom[colorIndex]) {
                let _itemBg = _item.getChildByName("bg")
                _itemBg.getComponent(Sprite).color = color().fromHEX(colorRandom[colorIndex])
            }
        }
        //(1, 1)随机在 5 个颜⾊中选取
        //其他各点的颜⾊在基准概率上进⾏调整
        /**
         *  (m, n - 1)所属颜⾊的概率增加 X%
            (m - 1, n)所属颜⾊的概率增加 X%
            若(m, n - 1)和(m - 1 ,n)同⾊，则该颜⾊的概率只增加 Y%
            其他颜⾊平分剩下的概率
         */
        let changeIndex1 = targetRwo * (targetCol - 1)
        let changeIndex2 = (targetRwo - 1) * targetCol
        let changeIndexItem1 = this.matrixList.getChildByName(`item${changeIndex1}`)
        let changeIndexItem2 = this.matrixList.getChildByName(`item${changeIndex2}`)
        if (changeIndexItem1 && changeIndexItem2) {
            let changeColorIndex1 = changeIndexItem1['data']
            let changeColorIndex2 = changeIndexItem2['data']

            if (changeColorIndex1 == changeColorIndex2) {
                //若(m, n - 1)和(m - 1 ,n)同⾊，则该颜⾊的概率只增加 Y%
                if (this.addY != 0) {
                    let changePro = this.probabilityArr[changeColorIndex1]
                    let endPro = changePro + this.addY;
                    this.probabilityArr[changeColorIndex1] = endPro
                    // 其他颜⾊平分剩下的概率
                    let changeOtherPro = (1 - endPro) / (colorRandom.length - 1)
                    if (changeOtherPro < 0) {
                        changeOtherPro = 0
                    }
                    for (let proIndex = 0; proIndex < this.probabilityArr.length; proIndex++) {
                        if (proIndex != changeColorIndex1) {
                            this.probabilityArr[proIndex] = changeOtherPro
                        }
                    }
                }
            } else {
                if (this.addX != 0) {
                    let changePro1 = this.probabilityArr[changeColorIndex1]
                    let endPro1 = changePro1 + this.addX;
                    this.probabilityArr[changeColorIndex1] = endPro1

                    //(m - 1, n)所属颜⾊的概率增加 X%
                    let changePro2 = this.probabilityArr[changeColorIndex2]
                    let endPro2 = changePro2 + this.addX;
                    this.probabilityArr[changeColorIndex2] = endPro2

                    // 其他颜⾊平分剩下的概率
                    let changeOtherPro = (1 - endPro1 - endPro2) / (colorRandom.length - 1)
                    if (changeOtherPro < 0) {
                        changeOtherPro = 0
                    }
                    for (let proIndex = 0; proIndex < this.probabilityArr.length; proIndex++) {
                        if (proIndex != changeColorIndex1 && proIndex != changeColorIndex2) {
                            this.probabilityArr[proIndex] = changeOtherPro
                        }
                    }
                }

            }
        }

        for (let index = 0; index < col * row; index++) {
            let _item = this.matrixList.getChildByName(`item${index + 1}`);
            if (_item) {
                if (index > 0) {
                    let colorIndex = this.getRandomReset(colorRandom, this.probabilityArr)
                    if (colorRandom[colorIndex]) {
                        let _itemBg = _item.getChildByName("bg")
                        _itemBg.getComponent(Sprite).color = color().fromHEX(colorRandom[colorIndex])
                    }
                }
            }
        }
    }

    starColorAni() {
        Tween.stopAllByTag(101)
        this.matrixList.children.forEach((_item) => {
            let _itemBg = _item.getChildByName("bg")
            _itemBg.setScale(0, 0, 0)
        })
        let aniIndex = 0
        this.matrixList.children.forEach((_item) => {
            let _itemBg = _item.getChildByName("bg")
            tween(_itemBg).delay(0.02 * aniIndex).to(0.1, { scale: new Vec3(1, 1, 1) }).tag(101).start()
            aniIndex++
        })
    }

    getRandomInt(min: number, max: number) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    getRandomReset(colorArr: string[], probability: number[]) {
        let sum = 0;
        let factor = 0;
        let random = Math.random();
        for (let proIndex = 0; proIndex < probability.length; proIndex++) {
            sum += probability[proIndex]
        }
        random *= sum;
        for (let index = 0; index < probability.length; index++) {
            factor += probability[index]
            if (random <= factor) {
                console.log("----resetIndex..." + index);

                return index//colorArr[index]
            }
        }
        return null
    }

    textChangeHandler1(event) {
        let inputStr = event;
        // 如果输入框内容不是数字，则将其设置为空字符串
        if (!/^\d*$/.test(inputStr)) {
            this.editBoxX.getComponent(EditBox).string = inputStr.replace(/\D/g, '');
        }
    }
    textChangeHandler2(event) {
        let inputStr = event;
        // 如果输入框内容不是数字，则将其设置为空字符串
        if (!/^\d*$/.test(inputStr)) {
            this.editBoxY.getComponent(EditBox).string = inputStr.replace(/\D/g, '');
        }
    }



    //测试2
    //有两层循环，每层循环都执行n次，总共执行n*n=n²次，时间复杂度为平方阶O(n)
    testClick() {
        let aArr = [10, 40, 5, 280];
        let bArr = [234, 5, 2, 148, 23];
        let vTarget = 42
        for (let aIndex = 0; aIndex < aArr.length; aIndex++) {
            let aNum = aArr[aIndex]
            let checkNum = vTarget - aNum;
            if (bArr.indexOf(checkNum) != -1) {
                console.log("----返回true");
                return true
            }
        }
        console.log("----返回false");
        return false
    }

    update(deltaTime: number) {

    }
}


